﻿
// Programmed By Sol Choe (Circulating List)

// 연결 리스트 (원형 연결 리스트)

/*#include <stdio.h>
#include <windows.h>

#define SAFE_DELETE(t) {delete t; t = NULL;}

struct NodeData
{
	int _NodeNum;
	char MyName[256];
	int MyAge;
	NodeData *NextNode;

	NodeData()
	{
		NextNode = NULL;
		MyAge = -1;
		_NodeNum = -1;
	}
};

class CircularList
{
public:
	CircularList();
	~CircularList();
public:
	void push_back();
	void push_front();
	void insert();
public:
	void pop_front();
	void pop_back();
	void delete_data();
public:
	int GetTotalCnt()
	{
		return this->TotalDataCnt;
	}
	void DisplayList();
private:
	NodeData *Head;
	int TotalDataCnt;
};

CircularList List;

CircularList::CircularList() : TotalDataCnt(0)
{
	Head = new NodeData;
}
CircularList::~CircularList()
{
	SAFE_DELETE(Head);
}
void CircularList::push_back()
{
	NodeData *NewPerData = new NodeData;

	printf("새로 들어갈 데이터의 나이를 적으시오 : ");
	scanf("%d",&NewPerData->MyAge);
	printf("새로 들어갈 데이터의 이름을 적으시오 : ");
	scanf("%s",NewPerData->MyName);

	NewPerData->_NodeNum = List.TotalDataCnt++;

	if(List.Head->NextNode == NULL)
	{
		List.Head->NextNode = NewPerData;
		NewPerData->NextNode = NewPerData;
	}
	else
	{
		NodeData *PointNode = List.Head->NextNode;

		PointNode = PointNode->NextNode;

		while(PointNode->NextNode != List.Head->NextNode)
			PointNode = PointNode->NextNode;
			
		PointNode->NextNode = NULL;

		NewPerData->NextNode = List.Head->NextNode;

		PointNode->NextNode = NewPerData;
	}
}
void CircularList::push_front()
{
	NodeData *NewPerData = new NodeData;

	printf("새로 들어갈 데이터의 나이를 적으시오 : ");
	scanf("%d",&NewPerData->MyAge);
	printf("새로 들어갈 데이터의 이름을 적으시오 : ");
	scanf("%s",NewPerData->MyName);

	NewPerData->_NodeNum = 0;

	if(List.Head->NextNode == NULL)
	{
		List.Head->NextNode = NewPerData;
		NewPerData->NextNode = NewPerData;
	}
	else
	{
		NodeData *PointNode = List.Head->NextNode;

		PointNode->_NodeNum++;

		PointNode = PointNode->NextNode;

		while(PointNode->NextNode != List.Head->NextNode)
		{
			PointNode->_NodeNum++;
			PointNode = PointNode->NextNode;
		}
	
		PointNode->_NodeNum++;

		PointNode->NextNode = NewPerData;

		NewPerData->NextNode = List.Head->NextNode;
		List.Head->NextNode = NewPerData;
	}
	List.TotalDataCnt++;
}
void CircularList::insert()
{
	BOOL IsNeedIter = false;

	NodeData *NewPerData = new NodeData;

	printf("삽입하고 싶은 방 번호를 입력하시오 : ");
	scanf("%d",&NewPerData->_NodeNum);
	printf("새로 들어갈 데이터의 나이를 적으시오 : ");
	scanf("%d",&NewPerData->MyAge);
	printf("새로 들어갈 데이터의 이름을 적으시오 : ");
	scanf("%s",NewPerData->MyName);

	NodeData *PointNode = List.Head->NextNode;

	if(List.Head->NextNode == NULL)
	{
		List.Head->NextNode = NewPerData;
		NewPerData->NextNode = NewPerData;
		NewPerData->_NodeNum = 0;
	}
	else
	{
		if(PointNode->_NodeNum == NewPerData->_NodeNum)
		{
			NodeData *PointNode = List.Head->NextNode;

			PointNode->_NodeNum++;

			PointNode = PointNode->NextNode;

			while(PointNode->NextNode != List.Head->NextNode)
			{
				PointNode->_NodeNum++;
				PointNode = PointNode->NextNode;
			}

			PointNode->NextNode = NewPerData;

			NewPerData->NextNode = List.Head->NextNode;
			List.Head->NextNode = NewPerData;
		}

		while(PointNode->NextNode != List.Head->NextNode)
		{
			if(PointNode->NextNode->_NodeNum == NewPerData->_NodeNum)
			{
				PointNode->NextNode->_NodeNum++;
				NewPerData->NextNode = PointNode->NextNode;
				PointNode->NextNode = NewPerData;
				IsNeedIter = true;
			}
			if(IsNeedIter)
				PointNode->_NodeNum++;

			PointNode = PointNode->NextNode;
		}
	}
	List.TotalDataCnt++;
}
void CircularList::pop_front()
{
	List.TotalDataCnt--;
}
void CircularList::pop_back()
{
	List.TotalDataCnt--;
}
void CircularList::delete_data()
{
	NodeData *DelNode = NULL;
	NodeData *PointNode = List.Head->NextNode;
	int Age = -1;
	char _Key[256];

	printf("삭제할 데이터의 나이를 적으시오 : ");
	scanf("%d",&Age);
	printf("삭제할 데이터의 이름을 적으시오 : ");
	scanf("%s",&_Key);

	if(PointNode == NULL)
	{
		printf("삭제할 데이터가 없습니다.");
	}
	else
	{
		if(!strcmp(PointNode->MyName,_Key) && PointNode->MyAge == Age)
		{
			DelNode = List.Head->NextNode;
			List.Head->NextNode = PointNode->NextNode;

			PointNode = PointNode->NextNode;
			while(PointNode->NextNode != DelNode)
				PointNode = PointNode->NextNode;

			PointNode->NextNode = List.Head->NextNode;

			DelNode->NextNode = NULL;
			SAFE_DELETE(DelNode);

		}
		else
		{
			NodeData *PrevNode = NULL;
			if(!strcmp(PointNode->NextNode->MyName,_Key) && PointNode->NextNode->MyAge == Age)
				PrevNode = PointNode;
			PointNode = PointNode->NextNode;
			while(PointNode != List.Head->NextNode)
			{
				if(!strcmp(PointNode->MyName,_Key) && PointNode->MyAge == Age)
				{
					PrevNode->NextNode = PointNode->NextNode;
					PointNode->NextNode = NULL;
					SAFE_DELETE(PointNode);
					break;
				}
				if(!strcmp(PointNode->NextNode->MyName,_Key) && PointNode->NextNode->MyAge == Age)
					PrevNode = PointNode;
				PointNode = PointNode->NextNode;
			}
		}
	}

	List.TotalDataCnt--;
}
void CircularList::DisplayList()
{
	NodeData *i = List.Head->NextNode;

	printf("이름 : %s, 나이 : %d, 방 번호 : %d\n", i->MyName, i->MyAge, i->_NodeNum);
	i = i->NextNode;

	for(; i != List.Head->NextNode; i = i->NextNode)
		printf("이름 : %s, 나이 : %d, 방 번호 : %d\n", i->MyName, i->MyAge, i->_NodeNum);
}

void main()
{
	int PointedMode = -1;
	while(1)
	{
		printf("전방 1번, 후방 2번, 지정 3번, 삭제 4번, 결과 5번, 나가기 0번: ");
		scanf("%d",&PointedMode);
		switch(PointedMode)
		{
		case 1:
			List.push_front();
			break;
		case 2:
			List.push_back();
			break;
		case 3:
			List.insert();
			break;
		case 4:
			List.delete_data();
			break;
		case 5:
			List.DisplayList();
			break;
		case 0:
			exit(0);
			break;
		}
	}
}
*/

// Programmed By Sol Choe (Stack)

// 스택 (1) (중위 연산자 -> 후위 연산자 변환)

/*
#include <stdio.h>
#include <windows.h>

#define SAFE_DELETE(t) {delete t; t = NULL;}
#define SAFE_DELETE_ARRAY(t) {delete []t; t = NULL;}

enum
{
	lparen = 1,
	rparen = 4,
	times = 3,
	divide = 3,
	plus = 2,
	minus = 2,
	operand = 0,
};

struct OperatorData
{
	char OperatorString[64];
	int PriorityStats;
	OperatorData()
	{
		for(int i=0; i<64; i++)
			OperatorString[i] = '\0';
	}
};

struct NodeData
{
	OperatorData MyData;
	NodeData *NextNode;

	NodeData()
	{
		NextNode = NULL;
	}
};

class LinkedList
{
public:
	LinkedList();
	~LinkedList();
public:
	void push_back(NodeData *NewPerData);
	void pop_back();
	NodeData *GetLastPointer();
	void clear();
public:
	int GetTotalCnt()
	{
		return TotalDataCnt;
	}
	NodeData *GetHead()
	{
		return Head;
	}
private:
	NodeData *Head;
	int TotalDataCnt;
};

LinkedList OperatorStack, TotalDataStack, ConvertedStack;

OperatorData ConstData[6], *ExprArray = NULL;

int DataCnt = 0, ConvertedDataCnt = 0;

LinkedList::LinkedList() : TotalDataCnt(0)
{
	Head = new NodeData;
}
LinkedList::~LinkedList()
{
	SAFE_DELETE(Head);
}
void LinkedList::push_back(NodeData *NewPerData)
{
	if(this->Head->NextNode == NULL)
		this->Head->NextNode = NewPerData;
	else
	{
		NodeData *PointNode = this->Head->NextNode;

		while(PointNode->NextNode != NULL)
			PointNode = PointNode->NextNode;

		PointNode->NextNode = NewPerData;
		NewPerData->NextNode = NULL;
	}

	this->TotalDataCnt++;
}
void LinkedList::pop_back()
{
	if(this->Head->NextNode == NULL)
		printf("삭제할 데이터가 존재치 않습니다.");
	else
	{
		NodeData *PointNode = this->Head->NextNode;
		NodeData *PrevNode = this->Head->NextNode;

		while(PrevNode->NextNode->NextNode != NULL)
			PrevNode = PrevNode->NextNode;

		while(PointNode->NextNode != NULL)
			PointNode = PointNode->NextNode;

		PrevNode->NextNode = NULL;

		PointNode->NextNode = NULL;

		this->TotalDataCnt--;
	}	
}
NodeData *LinkedList::GetLastPointer()
{
	NodeData *PointNode = this->Head->NextNode;

	while(PointNode->NextNode != NULL)
		PointNode = PointNode->NextNode;

	return PointNode;
}

void LinkedList::clear()
{
	if(this->Head->NextNode == NULL)
		return ;

	NodeData *PointNode = this->Head->NextNode;
	NodeData *PrevNode = this->Head->NextNode;

	while(PointNode->NextNode != NULL)
	{
		PointNode = PointNode->NextNode;
		SAFE_DELETE(PrevNode);
		PrevNode = PointNode;
	}
}

void DisplayResult()
{
	for(int i=0; i<DataCnt; i++)
		printf("수식 분리 결과 : %s\n", ExprArray[i].OperatorString);

	NodeData *CurrentNode = TotalDataStack.GetHead();

	while(CurrentNode->NextNode != NULL)
	{
		printf("변환 후 결과 : %s\n", CurrentNode->NextNode->MyData.OperatorString);
		CurrentNode = CurrentNode->NextNode;
	}
}

void CreateExprArray(char *ExpressionString)
{
	if(ExprArray != NULL)
	{
		SAFE_DELETE_ARRAY(ExprArray);
		TotalDataStack.clear();
	}

	char temp[128] = {0,};
	int OperatorCnt = 0, TotalCnt = 0;
	for(int i=0; i<strlen(ExpressionString)+1; i++)
	{
		BOOL IsFindOperator = false;
		switch(ExpressionString[i])
		{
		case '(':
		case '*':
		case '/':
		case '+':
		case '-':
		case ')':
			OperatorCnt++;
			break;
		default:
			for(int j=0; j<6; j++)
				if(ExpressionString[i+1] == ConstData[j].OperatorString[0])
					IsFindOperator = true;

			if(IsFindOperator)
				OperatorCnt++;
			break;
		}
	}

	DataCnt = OperatorCnt;
	ExprArray = new OperatorData[OperatorCnt];

	int StartIndex = 0, CurrentIndex = 0, PickIndex = 0;

	bool IsFindOperator = false;

	for(int i=0; i<strlen(ExpressionString) + 1; i++)
	{
		for(int j=0; j<6; j++) // 선택 지정 설정
		{
			if(ExpressionString[i] == ConstData[j].OperatorString[0] || ExpressionString[i] == NULL)
			{
				PickIndex = i;
				IsFindOperator = true;
				break;
			}
		}

		if(IsFindOperator)
		{
			bool IsDataInput = false;
			int CharCnt = 0;
			while(StartIndex < PickIndex)
			{
				if(ExpressionString[StartIndex] == ' ')
					StartIndex++;
				else
				{
					ExprArray[CurrentIndex].OperatorString[CharCnt++] = ExpressionString[StartIndex++];
					ExprArray[CurrentIndex].PriorityStats = operand;
					IsDataInput = true;
				}
			}
			if(StartIndex == PickIndex)
			{
				StartIndex++;
				IsFindOperator = false;
			}
			if(IsDataInput)
				CurrentIndex++;
			for(int j=0; j<6; j++)
			{
				if(ExpressionString[i] == ConstData[j].OperatorString[0])
				{
					ExprArray[CurrentIndex++] = ConstData[j];
					break;
				}
			}
		}
	}
}

void CompareOperator( int i )
{
	NodeData *CurrentPoint = OperatorStack.GetLastPointer();

	NodeData *InputData = new NodeData;
	InputData->MyData = ExprArray[i];

	if(InputData->MyData.PriorityStats != lparen || InputData->MyData.PriorityStats != rparen)
	{
		if(CurrentPoint->MyData.PriorityStats < ExprArray[i].PriorityStats)
			OperatorStack.push_back(InputData);
		else if(CurrentPoint->MyData.PriorityStats == ExprArray[i].PriorityStats)
			OperatorStack.push_back(InputData);
		else
		{
			OperatorStack.pop_back();
			if(CurrentPoint->MyData.PriorityStats != rparen)
				TotalDataStack.push_back(CurrentPoint);
			OperatorStack.push_back(InputData);
		}
	}
	else
		OperatorStack.push_back(InputData);
}
void ConvertMidFixToPostFix()
{
	TotalDataStack.clear();
	OperatorStack.clear();

	BOOL Inparen = false;
	for(int i=0; i<DataCnt; i++)
	{
		if(ExprArray[i].PriorityStats != operand)
		{
			if(ExprArray[i].PriorityStats == lparen)
				Inparen = true;
			if(ExprArray[i].PriorityStats == rparen)
			{
				Inparen = false;
				while(OperatorStack.GetLastPointer()->MyData.PriorityStats != lparen)
				{
					TotalDataStack.push_back(OperatorStack.GetLastPointer());
					OperatorStack.pop_back();
				}
			}
			if(Inparen)
			{
				if(OperatorStack.GetTotalCnt() <= 0)
				{
					NodeData *InputData = new NodeData;
					InputData->MyData = ExprArray[i];
					OperatorStack.push_back(InputData);
				}
				else
				{
					CompareOperator(i);
				}
			}
			else
			{
				if(OperatorStack.GetTotalCnt() <= 0)
				{
					NodeData *InputData = new NodeData;
					InputData->MyData = ExprArray[i];
					OperatorStack.push_back(InputData);
				}
				else
				{
					CompareOperator(i);
				}
			}
		}
		else
		{
			NodeData *InputData = new NodeData;
			InputData->MyData = ExprArray[i];
			TotalDataStack.push_back(InputData);
		}
	}
}

void main()
{
	ConstData[0].OperatorString[0] = '(';
	ConstData[0].PriorityStats = lparen;
	ConstData[1].OperatorString[0] = '*';
	ConstData[1].PriorityStats = times;
	ConstData[2].OperatorString[0] = '/';
	ConstData[2].PriorityStats = divide;
	ConstData[3].OperatorString[0] = '+';
	ConstData[3].PriorityStats = plus;
	ConstData[4].OperatorString[0] = '-';
	ConstData[4].PriorityStats = minus;
	ConstData[5].OperatorString[0] = ')';
	ConstData[5].PriorityStats = rparen;

	int Choose = -1;
	char ExpressionString[256];
	while(1)
	{
		printf("수식 생성 1번, 생성된 식을 후위 표기법으로 변환 2번, 출력 3번, 종료 0번 : ");
		scanf("%d",&Choose);
		fflush(stdin);
		switch(Choose)
		{
		case 1:
			printf("수식을 입력하세요 : ");
			gets(ExpressionString);
			CreateExprArray(ExpressionString);
			Choose = -1;
			break;
		case 2:
			ConvertMidFixToPostFix();
			Choose = -1;
			break;
		case 3:
			DisplayResult();
			break;
		case 0:
			exit(1);
			break;
		}
	}
}
*/

// Programmed By Sol Choe (Stack)

// 스택 (2) (8방향 미로찾기)

/*#include <stdio.h>
#include <windows.h>

#define SAFE_DELETE(t) {delete t; t = NULL;}
#define SAFE_DELETE_ARRAY(t) {delete []t; t = NULL;}

const int Width = 8, Height = 8, NumofDir = 8;

enum
{
	Novisit = 0,
	Wall,
	Visited,
};

int DirOffset[NumofDir][2] = {
	{0,-1}, {1,-1}, {1,0}, {1,1},
	{0,1}, {-1,1}, {-1,0}, {-1,-1},
};

struct PathData
{
	int x,y;
	int Direction;
};

struct NodeData
{
	PathData MyData;
	NodeData *NextNode;

	NodeData()
	{
		NextNode = NULL;
	}
};

PathData StartPos, EndPos;

LinkedList PathStack, NoPathStack;

int MazeMap[Width][Height] = {
								{0,0,0,0,0,0,0,0},
								{1,0,1,1,1,0,1,1},
								{0,0,0,0,0,0,0,1},
								{1,0,1,1,1,0,1,0},
								{1,0,1,0,1,0,1,0},
								{0,0,1,0,1,0,1,1},
								{1,0,1,0,1,0,0,0},
								{1,0,0,0,1,1,1,0},
							};

void ShowPath()
{
	printf("Finded Path = \n");
	for(NodeData *i = PathStack.GetHead()->NextNode; i != PathStack.GetLastPointer()->NextNode; i = i->NextNode)
	{
		MazeMap[i->MyData.y][i->MyData.x] = Visited;
		printf("<x = %d  y = %d>\n", i->MyData.x, i->MyData.y);
	}
}

bool InitMap()
{
	if(StartPos.x >= 0 && StartPos.x < Width && StartPos.y >= 0 && StartPos.y < Height)
	{
			if(MazeMap[StartPos.y][StartPos.x] == Novisit && MazeMap[EndPos.y][EndPos.x] == Novisit)
				return true;
			else
				return false;
	}
	else
		return false;
}

bool FindPath()
{
	bool IsCollided = false, IsMove = false;
	int CheckX = 0, CheckY = 0;
	while(StartPos.x != EndPos.x || StartPos.y != EndPos.y)
	{
		NodeData *NextPos = new NodeData;

		// 방향 지정한다.
		if(!IsMove)
		{
			for(int i=0; i<NumofDir; i++)
			{
				CheckX = StartPos.x + DirOffset[i][0];
				CheckY = StartPos.y + DirOffset[i][1];

				if(CheckX >= 0 && CheckX < Width && CheckY >= 0 && CheckY < Height && MazeMap[CheckY][CheckX] == Novisit)
				{
					StartPos.Direction = i;
					NextPos->MyData.Direction = i;
					IsCollided = false;
					IsMove = true;
					break;
				}
			}
		}
		else
		{
			CheckX = StartPos.x + DirOffset[StartPos.Direction][0];
			CheckY = StartPos.y + DirOffset[StartPos.Direction][1];
			NextPos->MyData.Direction = StartPos.Direction;
		}

		if(IsCollided)
		{
			NodeData *CurrentPos = new NodeData;
			CurrentPos->MyData = StartPos;
			NoPathStack.push_back(CurrentPos);
			NextPos = PathStack.GetLastPointer();
			PathStack.pop_back();
			StartPos = NextPos->MyData;
			SAFE_DELETE(NextPos);
			MazeMap[StartPos.y][StartPos.x] = Visited;
		}

		// 이동 전 앞의 곳에 충돌 여부를 확인한다.
		if(CheckX >= 0 && CheckX < Width && CheckY >= 0 && CheckY < Height)
		{
			if(MazeMap[CheckY][CheckX] != Novisit)
			{
				IsCollided = true;
				IsMove = false;
			}
		}
		else
		{
			IsCollided = true;
			IsMove = false;
		}
		
		// 방향 지정된 경우 전진한다.
		if(StartPos.Direction >= 0)
		{
			if(!IsCollided)
			{
				if(CheckX >= 0 && CheckX < Width && CheckY >= 0 && CheckY < Height && MazeMap[CheckY][CheckX] == Novisit)
				{
					NextPos->MyData.x = StartPos.x + DirOffset[StartPos.Direction][0];
					NextPos->MyData.y = StartPos.y + DirOffset[StartPos.Direction][1];

					StartPos.x += DirOffset[StartPos.Direction][0];
					StartPos.y += DirOffset[StartPos.Direction][1];
				}
			}
		}

		// 충돌 전까지 스택에 자료를 넣는다.
		if(!IsCollided)
		{
 			PathStack.push_back(NextPos);
			MazeMap[StartPos.y][StartPos.x] = Visited;
		}

		// 스택에 자료가 없을 경우 빠져나온다.
		if(PathStack.GetTotalCnt() <= 0)
			return false;
	}
	if(NoPathStack.GetTotalCnt() > 0)
	{
		for(NodeData *i = NoPathStack.GetHead()->NextNode; i != NoPathStack.GetLastPointer()->NextNode; i = i->NextNode)
			MazeMap[i->MyData.y][i->MyData.x] = Novisit;
	}
	return true;
}

void DisplayMap()
{
	for(int i=0; i<Height; i++)
	{
		printf("\t\t\t");
		for(int j=0; j<Width; j++)
		{
			if(MazeMap[i][j] == Wall)
				printf("*");
			else if(MazeMap[i][j] == Novisit)
				printf(" ");
			else
				printf(".");
			
		}
		printf("\n");
	}
}

void main()
{
	printf("\t\t\t초기의 맵\n");
	DisplayMap();
	
	while(1)
	{
		printf("\n시작 x점, y점을 입력하세요 : ");
		scanf("%d %d",&StartPos.x, &StartPos.y);
		printf("\n끝 x점, y점을 입력하세요 : ");
		scanf("%d %d",&EndPos.x, &EndPos.y);

		if(InitMap())
		{
			NodeData *StartNode = new NodeData;
			StartNode->MyData = StartPos;
			PathStack.push_back(StartNode);
			if(FindPath())
			{
				ShowPath();
				break;
			}
			else
				printf("길찾기를 하지 못했습니다.\n");
		}
		else
			printf("잘못된 시작지점 혹은 끝지점을 선정하셨습니다.\n");
	}
	printf("\t\t\t미로찾기 알고리즘 후의 맵\n");
	DisplayMap();
}*/

// Programmed By Sol Choe (Queue)

// 큐 (n개 은행원 다중 분산 은행 처리 시뮬레이션)

/*#include <stdio.h>
#include <windows.h>

#define SAFE_DELETE(t) {delete t; t = NULL;}
#define SAFE_DELETE_ARRAY(t) {delete []t; t = NULL;}

struct Customer
{
	char *Name;
	int ArrivalTime, ServiceTime, CustomerNumber;
};

struct NodeData
{
	Customer MyData;
	NodeData *NextNode;

	NodeData()
	{
		NextNode = NULL;
	}
};

Queue CustomerArriQueue, CustomerWaitQueue;

const int StartTime = 0, EndTime = 10;
int EmployeeCnt = 0;

class Employee
{
public:
	Employee();
	~Employee();
public:
	void ServiceToCustomer(int CurrentTime);
public:
	NodeData *ServedCustomer;
	int EmployeeNumber, ServEndTime;
	BOOL IsService;
public:
	Queue ResultQueue;
};

Employee::Employee() : IsService(false), ServedCustomer(NULL), EmployeeNumber(0)
{
}
Employee::~Employee()
{
	if(ServedCustomer != NULL)
		SAFE_DELETE(ServedCustomer);
}
void Employee::ServiceToCustomer(int CurrentTime)
{
	if(CurrentTime < ServEndTime)
		return ;
	else
	{
		ResultQueue.push_back(ServedCustomer);
		IsService = false;
	}
}

Employee *CurrentEmployee = NULL;

void InitCustomer(int _ArrivalTime, int _ServiceTime, char *_Name)
{
	NodeData *NewCustomer = new NodeData;

	NewCustomer->MyData.ArrivalTime = _ArrivalTime;
	NewCustomer->MyData.ServiceTime = _ServiceTime;
	NewCustomer->MyData.Name = _Name;

	CustomerArriQueue.push_back(NewCustomer);
}

void ServingProcess()
{
	for(int i=0; i<=EndTime; i++)
	{
		for(int j=0; j<EmployeeCnt; j++)
		{
			if(!CurrentEmployee[j].IsService)
			{
				NodeData *CurrentData = CustomerArriQueue.GetFirstPointer();
				if(CurrentData != NULL)
				{
					if(CurrentData->MyData.ArrivalTime == i)
					{
						CustomerArriQueue.pop_front();
						CustomerWaitQueue.push_back(CurrentData);
						CurrentEmployee[j].IsService = true;
						CurrentEmployee[j].ServEndTime = i + CustomerWaitQueue.GetFirstPointer()->MyData.ServiceTime;
						CurrentEmployee[j].ServedCustomer = CustomerWaitQueue.GetFirstPointer();
						CustomerWaitQueue.pop_front();
					}
				}
			}
			else
				CurrentEmployee[j].ServiceToCustomer(i);
		}
	}
}

void ViewResult()
{
	for(int i=0; i<EmployeeCnt; i++)
	{
		NodeData *FirstPointer = CurrentEmployee[i].ResultQueue.GetFirstPointer();
		NodeData *LastPointer = CurrentEmployee[i].ResultQueue.GetLastPointer();

		if(FirstPointer != NULL)
		{
			for(NodeData *j = FirstPointer; j != LastPointer; j = j->NextNode)
			{
				printf("%d번째 은행원이 처리한 고객 %s, 도착 시간 = %d, 서비스 시간 = %d\n",
					i, j->MyData.Name, j->MyData.ArrivalTime, j->MyData.ServiceTime);
			}
			printf("%d번째 은행원이 처리한 고객 %s, 도착 시간 = %d, 서비스 시간 = %d\n",
				i, LastPointer->MyData.Name, LastPointer->MyData.ArrivalTime, LastPointer->MyData.ServiceTime);
		}
	}
}

void main()
{
	printf("은행원의 수를 입력하여 주세요 : ");
	scanf("%d",&EmployeeCnt);

	if(EmployeeCnt > 0)
	{
		CurrentEmployee = new Employee[EmployeeCnt];

		for(int i=0; i<EmployeeCnt; i++)
			CurrentEmployee[i].EmployeeNumber = i;

		InitCustomer(0,3,"첫번쨰");
		InitCustomer(1,3,"두번쨰");
		InitCustomer(2,3,"세번쨰");
		InitCustomer(3,2,"네번쨰");
		InitCustomer(4,4,"다섯번쨰");
		InitCustomer(5,5,"여섯번쨰");

		ServingProcess();

		ViewResult();
	}
	else
		return ;
}*/

// Sample Program (Recursive Function)

// 재귀 함수 (재귀호출을 이용한 하노이의 탑)

/*#include <stdio.h>

void hanoi_tower(int n, char from, char temp, char to)
{
	if(n == 1)
		printf("원판 1을 %c에서 %c로 옮겼습니다.\n", from, to);
	else
	{
		hanoi_tower(n-1,from,to,temp);
		printf("원판 %i를 %c에서 %c로 옮겼습니다.\n", n, from, to);
		hanoi_tower(n-1,temp,from,to);
	}
}

void main()
{
	char from = 'A';
	char temp = 'B';
	char to = 'C';

	hanoi_tower(4,from,temp,to);
}*/

// Programmed By Sol Choe (Recursive Function)

// 재귀 함수 (반복호출을 통한 하노이의 탑)

/*#include "stdafx.h"
#include "Data.h"
#include "Stack.h"
#include "Queue.h"

int MaxSlotCnt = 0, PlateCnt = 0;

Stack *PlateStorage = NULL;

NodeData *Plate = NULL;

bool InitPlate()
{
	printf("먼저 삽입될 원판의 크기를 입력하세요 : (2이상 자연수)");
	scanf("%d",&PlateCnt);

	if(PlateCnt > 0)
	{
		Plate = new NodeData[PlateCnt];

		int CurrentIndex = 0;
		for(int i=PlateCnt; i > 0; i--)
		{
			Plate[CurrentIndex].MyData.SizeofPlate = i;
			PlateStorage[0].push_back(&Plate[CurrentIndex++]);
		}

		for(int i=0; i<MaxSlotCnt; i++)
		{
			NodeData *FirstNode = PlateStorage[i].GetHead();
			NodeData *LastNode = PlateStorage[i].GetLastPointer();
			for(NodeData *j = FirstNode; j != LastNode; j = j->NextNode)
				printf("%d번쨰에 삽입된 %d크기의 원판\n", i, j->MyData.SizeofPlate);

			if(LastNode != NULL)
				printf("%d번쨰에 삽입된 %d크기의 원판\n", i, LastNode->MyData.SizeofPlate);	
		}
			
		return true;
	}
	else
	{
		printf("크기가 너무 작습니다. 원판을 생성할 수 없습니다.\n");
		return false;
	}
}

void CalcSlot()
{
	int PtSlot = -1, PtDataSize = 0, NextSlot = -1;

	printf("꺼내고자 하는 데이터가 위치한 슬롯의 번호를 입력하세요 : ");
	scanf("%d",&PtSlot);
	printf("꺼내고자 하는 데이터가 위치한 데이터의 크기를 입력하세요 : ");
	scanf("%d",&PtDataSize);
	printf("옮기려는 슬롯의 번호를 입력하세요 : ");
	scanf("%d",&NextSlot);

	if(PtSlot >= 0 && PtDataSize > 0 && NextSlot > 0)
	{
		NodeData *FirstNode = PlateStorage[PtSlot].GetHead();
		NodeData *LastNode = PlateStorage[PtSlot].GetLastPointer();
		NodeData *FindedNode = NULL;

		for(NodeData *i = FirstNode; i != LastNode; i = i->NextNode)
		{
			if(i->MyData.SizeofPlate == PtDataSize)
			{
				FindedNode = i;
				break;
			}
		}

		if(FindedNode != NULL)
		{
			int PickedSlot = -1;
			NodeData *CurrentPt = NULL;
			// 임시로 옮길 슬롯을 정하는 과정.
			for(int i=0; i<MaxSlotCnt; i++)
			{
				int Total = PlateStorage[i].GetTotalCnt();
				if(Total <= 0)
				{
					if(NextSlot != i)
					{
						PickedSlot = i;
						break;
					}
				}
			}
			// 임시 정해진 슬롯으로 정해진 데이터 전까지 삽입 한다.
			if(PickedSlot > 0)
			{
				CurrentPt = PlateStorage[PtSlot].GetLastPointer();
				while(CurrentPt != FindedNode)
				{
					PlateStorage[PickedSlot].push_back(CurrentPt);
					PlateStorage[PtSlot].pop_back();
					CurrentPt = PlateStorage[PtSlot].GetLastPointer();
				}
				CurrentPt->NextNode = NULL;
				PlateStorage[NextSlot].push_back(CurrentPt);

				while(PlateStorage[PickedSlot].GetTotalCnt() > 0)
				{
					CurrentPt = PlateStorage[PickedSlot].GetLastPointer();
					PlateStorage[NextSlot].push_back(CurrentPt);
					PlateStorage[PickedSlot].pop_back();
				}
			}
		}
	}
	else
		printf("슬롯의 위치와 크기가 불분명합니다.\n");
}

void ViewSlot()
{
	printf("연산 후의 모습\n");
	for(int i=0; i<MaxSlotCnt; i++)
	{
		NodeData *FirstNode = PlateStorage[i].GetHead();
		NodeData *LastNode = PlateStorage[i].GetLastPointer();
		for(NodeData *j = FirstNode; j != LastNode; j = j->NextNode)
			printf("%d번쨰에 삽입된 %d크기의 원판\n", i, j->MyData.SizeofPlate);

		if(LastNode != NULL)
			printf("%d번쨰에 삽입된 %d크기의 원판\n", i, LastNode->MyData.SizeofPlate);	
	}
}

void main()
{
	while(1)
	{
		printf("반복 호출 이용한 하노이 탑 프로그램\n");
		printf("저장할 슬롯의 갯수를 입력하시오 : ");
		scanf("%d",&MaxSlotCnt);

		if(MaxSlotCnt >= 3)
		{
			PlateStorage = new Stack[MaxSlotCnt];

			if(InitPlate())
			{
				CalcSlot();
				ViewSlot();
				break;
			}
			else
				SAFE_DELETE_ARRAY(PlateStorage);
		}
		else
			printf("최소 조건이 만족되지 않습니다. 다시 입력하세요.\n");
	}
}*/

// Programmed By Sol Choe (Tree)

/*
// 삽입시 사용될 키
enum
{
	Left,
	Right,
};

// 찾을 떄 사용할 방법
enum
{
	PreOrder,
	InOrder,
	PostOrder,
	LevelOrder,
};

class BinaryTree
{
public:
	BinaryTree();
	~BinaryTree();
// 사용할 함수 구현.
public:
	NodeData *GetRoot()
	{
		return RootNode;
	}
public:
	bool InitTree(int Key);
	NodeData *getLeftChildNode(NodeData *CurrentNode);
	NodeData *getRightChildNode(NodeData *CurrentNode);
	void InsertNode(int InsertKey, NodeData *PointNode);
	NodeData *SearchNode(int SearchingMethod, int key);
	void DeleteTree();
public:
	void CopyTree(BinaryTree *CurrentTree);
	bool IsTreeEqual(BinaryTree *SourceNode, BinaryTree *DestNode);
	int getTreeNodeCnt(BinaryTree *SourceNode);
	int getTreeEndNodeCnt(BinaryTree *SourceNode);
	int getTreeHeight(BinaryTree *SourceNode);
	void ViewTreeNode();
// 내부 함수 구현.
private:
	void InsertLeftChildNode(NodeData *CurrentNode);
	void InsertRightChildNode(NodeData *CurrentNode);
private:
	NodeData *PreOrderSearch(int Key);
	NodeData *InOrderSearch(int Key);
	NodeData *PostOrderSearch(int Key);
	NodeData *LevelOrderSearch(int Key);
private:
	NodeData *RootNode;
	Stack SearchStack;
};

BinaryTree MyTree;

NodeData *CurrentPoint = NULL;

BinaryTree::BinaryTree() : RootNode(NULL)
{

}
BinaryTree::~BinaryTree()
{

}

bool BinaryTree::InitTree(int Key)
{
	if(Key > 0 && RootNode == NULL)
	{
		RootNode = new NodeData;
		RootNode->MyData = Key;
		printf("트리를 초기화하였습니다.\n");
		return true;
	}
	else
	{
		printf("트리의 초기화에 실패하였거나 트리가 초기화 되어있습니다.\n");
		return false;
	}
}
NodeData *BinaryTree::getLeftChildNode(NodeData *CurrentNode)
{
	if(CurrentNode != NULL)
	{
		if(CurrentNode->RightNode != NULL)
			return CurrentNode->RightNode;
		else
		{
			printf("연결된 노드가 존재하지 않습니다.\n");
			return NULL;
		}
	}
	else
	{
		printf("현재 노드가 비어있는 값입니다.\n");
		return NULL;
	}
}
NodeData *BinaryTree::getRightChildNode(NodeData *CurrentNode)
{
	if(CurrentNode != NULL)
	{
		if(CurrentNode->RightNode != NULL)
			return CurrentNode->RightNode;
		else
		{
			printf("연결된 노드가 존재하지 않습니다.\n");
			return NULL;
		}
	}
	else
	{
		printf("현재 노드가 비어있는 값입니다.\n");
		return NULL;
	}
}
void BinaryTree::InsertNode(int InsertKey, NodeData *PointNode)
{
	if(PointNode != NULL)
	{
		switch(InsertKey)
		{
		case Left:
			InsertLeftChildNode(PointNode);
			break;
		case Right:
			InsertRightChildNode(PointNode);
			break;
		}
	}
	else
	{
		printf("현재 노드가 비어있는 값입니다.\n");
		return ;
	}
}
NodeData *BinaryTree::SearchNode(int SearchingMethod, int key)
{
	NodeData *RetNode = NULL;

	switch(SearchingMethod)
	{
	case PreOrder:
		printf("전위 순회를 이용한 탐색 실행.\n");
		RetNode = PreOrderSearch(key);
		break;
	case InOrder:
		RetNode = InOrderSearch(key);
		break;
	case PostOrder:
		RetNode = PostOrderSearch(key);
		break;
	case LevelOrder:
		RetNode = LevelOrderSearch(key);
		break;
	}

	return RetNode;
}
void BinaryTree::DeleteTree()
{

}
void BinaryTree::CopyTree(BinaryTree *CurrentTree)
{
	if(CurrentTree != NULL)
	{
		NodeData *PointNode = GetRoot();
		NodeData *TempTreeNode = CurrentTree->GetRoot();
		while(PointNode != NULL)
		{
			// 순서에 따라 왼쪽 서브트리를 먼저 탐색한다.
			while(PointNode != NULL)
			{
				TempTreeNode->LeftNode = new NodeData;
				*TempTreeNode->LeftNode = *PointNode;
				SearchStack.push_back(PointNode);
				PointNode = PointNode->LeftNode;
				TempTreeNode = TempTreeNode->LeftNode;
			}

			// 찾던 중 단말 노드를 만나게되면 스택에서 삭제한다.
			TempTreeNode = SearchStack.GetLastPointer();
			if(TempTreeNode->LeftNode == NULL && TempTreeNode->RightNode == NULL)
			{
				SearchStack.pop_back();
				TempTreeNode = SearchStack.GetLastPointer();

				if(TempTreeNode != NULL)
				{
					if(TempTreeNode->LeftNode != NULL)
						TempTreeNode->LeftNode = NULL;
				}
			}
		}
	}
	else
	{
		printf("현재 초기화되있지 않습니다.\n");
		return ;
	}
}
bool BinaryTree::IsTreeEqual(BinaryTree *SourceNode, BinaryTree *DestNode)
{
return false;
}
int BinaryTree::getTreeNodeCnt(BinaryTree *SourceNode)
{
return NULL;
}
int BinaryTree::getTreeEndNodeCnt(BinaryTree *SourceNode)
{
return NULL;
}
int BinaryTree::getTreeHeight(BinaryTree *SourceNode)
{
return NULL;
}
void BinaryTree::ViewTreeNode()
{

}
void BinaryTree::InsertLeftChildNode(NodeData *CurrentNode)
{
	if(CurrentNode != NULL)
	{
		if(CurrentNode->LeftNode == NULL)
		{
			CurrentNode->LeftNode = new NodeData;
			if(CurrentNode->LeftNode != NULL)
			{
				printf("새로 추가된 노드에 삽입할 데이터를 입력하시오 : ");
				scanf("%d",&CurrentNode->LeftNode->MyData);
			}
			else
				printf("메모리 할당 에러\n");
		}
		else
			printf("노드에 값이 있습니다.\n");
	}
	else
		printf("현재 노드가 비어있는 값입니다.\n");
}
void BinaryTree::InsertRightChildNode(NodeData *CurrentNode)
{
	if(CurrentNode != NULL)
	{
		if(CurrentNode->RightNode == NULL)
		{
			CurrentNode->RightNode = new NodeData;
			if(CurrentNode->RightNode != NULL)
			{
				printf("새로 추가된 노드에 삽입할 데이터를 입력하시오 : ");
				scanf("%d",&CurrentNode->RightNode->MyData);
			}
			else
				printf("메모리 할당 에러\n");
		}
		else
			printf("노드에 값이 있습니다.\n");
	}
	else
		printf("현재 노드가 비어있는 값입니다.\n");
}
NodeData *BinaryTree::PreOrderSearch(int Key)
{
	if(Key > 0)
	{
		// 초기 루트를 삽입한다. (현재 노드)
		NodeData *PointNode = GetRoot();
		SearchStack.push_back(PointNode);

		while(1)
		{
			// 순서에 따라 왼쪽 서브트리를 먼저 탐색한다.
			while(PointNode != NULL)
			{
				if(Key != PointNode->MyData)
				{
					SearchStack.push_back(PointNode);
					printf("방문한 길 = %d\n",PointNode->MyData);
					PointNode = PointNode->LeftNode;
				}
				else
					return PointNode;
			}

			// 찾던 중 단말 노드를 만나게되면 스택에서 삭제한다.
			if(SearchStack.GetLastPointer() != NULL)
			{
				if(SearchStack.GetLastPointer()->RightNode == NULL)
					SearchStack.pop_back();
				else
				{
					PointNode = SearchStack.GetLastPointer()->RightNode;
					SearchStack.pop_back();
				}
			}
			else
				break;
		}
		printf("값을 찾지 못했습니다.\n");
		return NULL;
	}
	else
	{
		printf("찾고자하는 값이 너무 작습니다.\n");
		return NULL;
	}
}
NodeData *BinaryTree::InOrderSearch(int key)
{
return NULL;
}
NodeData *BinaryTree::PostOrderSearch(int key)
{
return NULL;
}
NodeData *BinaryTree::LevelOrderSearch(int key)
{
return NULL;
}

void main()
{
	MyTree.InitTree(1);
	CurrentPoint = MyTree.GetRoot();
	MyTree.InsertNode(Left,CurrentPoint);
	MyTree.InsertNode(Right,CurrentPoint);
	CurrentPoint = CurrentPoint->LeftNode;

	MyTree.InsertNode(Left,CurrentPoint);
	MyTree.InsertNode(Right,CurrentPoint);
	CurrentPoint = CurrentPoint->RightNode;

	MyTree.InsertNode(Left,CurrentPoint);

	CurrentPoint = MyTree.GetRoot();
	CurrentPoint = CurrentPoint->LeftNode;
	CurrentPoint = CurrentPoint->LeftNode;
	MyTree.InsertNode(Left,CurrentPoint);
	MyTree.InsertNode(Right,CurrentPoint);

	CurrentPoint = MyTree.GetRoot();
	CurrentPoint = CurrentPoint->RightNode;
	MyTree.InsertNode(Left,CurrentPoint);
	MyTree.InsertNode(Right,CurrentPoint);
	CurrentPoint = CurrentPoint->LeftNode;
	MyTree.InsertNode(Right,CurrentPoint);

	CurrentPoint = MyTree.GetRoot();
	CurrentPoint = CurrentPoint->RightNode;
	CurrentPoint = CurrentPoint->RightNode;
	MyTree.InsertNode(Left,CurrentPoint);
	MyTree.InsertNode(Right,CurrentPoint);

	CurrentPoint = MyTree.SearchNode(PreOrder, 9);

	if(CurrentPoint != NULL)
	{
		printf("찾은 노드 값 = %d\n",CurrentPoint->MyData);
	}
}*/

// Programmed By Sol Choe (Graph)

// 그래프 (플로이드, 다익스트라, 도달 가능성 미해결. 잠시 보류)

/*#include "stdafx.h"
#include "Data.h"
#include "Queue.h"
#include "LinkedList.h"

const int MAX = 99999;

enum
{
	NOTUSED = 0,
	USED,
};

class Graph
{
public:
	Graph();
	~Graph();
public:
	bool CreateGraph();
	void CreateNode(int SelectID);
	void DeleteNode(int DeleteID);
	void CreateVertex(int StartID, int EndID);
	void DeleteVertex(int StartID, int EndID);
public:
	bool RunDijkstra(int StartID, int EndID);
	bool RunFloyd(int StartID);
public:
	void CurrentView();
private:
	int MaxNodeCnt;
	int CurrentVertexCnt;
	int TypeofVertex;
	bool *NodeList;
	LinkedList *VertexList;
};

Graph::Graph() : MaxNodeCnt(0), CurrentVertexCnt(0), TypeofVertex(-1), VertexList(NULL), NodeList(NULL)
{

}

Graph::~Graph()
{
	SAFE_DELETE(NodeList);

	VertexList->clear();
	SAFE_DELETE(VertexList);
}

bool Graph::CreateGraph()
{
	printf("노드의 최대 갯수를 입력하시오 : ");
	scanf("%d",&MaxNodeCnt);

	printf("그래프의 종류를 입력하시오 : (1. 무방향 그래프 2. 방향 그래프) ");
	scanf("%d",&TypeofVertex);

	VertexList = new LinkedList[MaxNodeCnt];

	NodeList = new bool[MaxNodeCnt];

	for(int i=0; i<MaxNodeCnt; i++)
		NodeList[i] = NOTUSED;

	if(VertexList != NULL)
		return true;
	else
		return false;
}
void Graph::CreateNode(int SelectID)
{
	if(SelectID < MaxNodeCnt)
		NodeList[SelectID] = USED;
	else
	{
		printf("유효범위를 넘었습니다.\n");
		return ;
	}
}
void Graph::DeleteNode(int DeleteID)
{
	if(DeleteID < MaxNodeCnt)
		NodeList[DeleteID] = NOTUSED;
	else
	{
		printf("유효범위를 넘었거나 삭제되어 있습니다.\n");
		return ;
	}
}
void Graph::CreateVertex(int StartID, int EndID)
{
	if(&NodeList[StartID] != NULL && &NodeList[EndID] != NULL)
	{
		if(NodeList[StartID] && NodeList[EndID])
		{
			NodeData *NewVertex = new NodeData;
			printf("간선의 가중치 값을 입력하세요 : ");
			scanf("%d",&NewVertex->Data.weight);
			NewVertex->Data.vertexID = EndID;

			NodeData *i = VertexList[StartID].GetFirstPointer();
			for(i = VertexList[StartID].GetFirstPointer(); i != VertexList[StartID].GetLastPointer(); i = i->NextNode)
			{
				if(i->Data.vertexID == NewVertex->Data.vertexID)
				{
					printf("이미 연결되어 있는 선입니다.\n");
					return ;
				}
			}
			if(i != NULL)
			{
				if(i->Data.vertexID == NewVertex->Data.vertexID)
				{
					printf("이미 연결되어 있는 선입니다.\n");
					return ;
				}
			}

			if(TypeofVertex == 1)
			{
				NodeData *ReverseVertex = new NodeData;
				ReverseVertex->Data.weight = NewVertex->Data.weight;
				ReverseVertex->Data.vertexID = StartID;

				NodeData *i = VertexList[EndID].GetFirstPointer();

				for(i = VertexList[EndID].GetFirstPointer(); i != VertexList[EndID].GetLastPointer(); i = i->NextNode)
				{
					if(i->Data.vertexID == NewVertex->Data.vertexID)
					{
						printf("이미 연결되어 있는 선입니다.\n");
						return ;
					}
				}
				if(i != NULL)
				{
					if(i->Data.vertexID == NewVertex->Data.vertexID)
					{
						printf("이미 연결되어 있는 선입니다.\n");
						return ;
					}
				}

				VertexList[EndID].push_back(ReverseVertex);
				VertexList[StartID].push_back(NewVertex);
			}
			else if(TypeofVertex == 2)
				VertexList[StartID].push_back(NewVertex);
		}
	}
	else
	{
		printf("메모리 할당이 되어있지 않습니다.\n");
		return ;
	}
}
void Graph::DeleteVertex(int StartID, int EndID)
{
	for(int i=0; i<MaxNodeCnt; i++)
	{
		for(NodeData *FindNode = VertexList[i].GetFirstPointer(); FindNode != VertexList[i].GetLastPointer(); FindNode = FindNode->NextNode)
		{
			if(FindNode->Data.vertexID == EndID && i == StartID)
			{
				if(VertexList[i].Delete(FindNode))
				{
					printf("삭제하였습니다.\n");
					NodeList[i] = false;
				}
				break;
			}
		}
	}
}
bool Graph::RunDijkstra(int StartID, int EndID)
{
	if(StartID >= 0 && StartID < MaxNodeCnt && EndID >= 0 && EndID < MaxNodeCnt)
	{
		int LeastID, LeastWeight;
		bool *IsListVisit = new bool[MaxNodeCnt];
		LinkedList *TempList = new LinkedList[MaxNodeCnt];
		LinkedList Path;

		// 노드 세팅.
		for(int i=0; i<MaxNodeCnt; i++)
		{
			TempList[i] = VertexList[i];
			IsListVisit[i] = false;
		}

		IsListVisit[StartID] = true;

		for(int k=0; k<MaxNodeCnt-1; k++)
		{
			NodeData *i = NULL, *j = NULL;

			// 현재 위치의 최단거리를 찾기 위한 최소 가중치를 찾는다.
			for(i = TempList[StartID].GetFirstPointer(); i != TempList[StartID].GetLastPointer(); i = i->NextNode)
			{
				for(j = TempList[StartID].GetFirstPointer(); j != TempList[StartID].GetLastPointer(); j = j->NextNode)
				{
					if(i->Data.weight < j->Data.weight && !IsListVisit[i->Data.vertexID])
					{
						LeastID = i->Data.vertexID;
						LeastWeight = i->Data.weight;
						IsListVisit[LeastID] = true;
					}
				}

				if(i->Data.weight < j->Data.weight && !IsListVisit[i->Data.vertexID])
				{
					LeastID = i->Data.vertexID;
					LeastWeight = i->Data.weight;
					IsListVisit[LeastID] = true;
				}
			}
		}

		for(NodeData *i = Path.GetFirstPointer(); i != Path.GetLastPointer(); i = i->NextNode)
		{
			printf("%d\n",i->Data.vertexID);
		}
		return true;	
	}
	else
	{
		printf("최대 범위 값을 넘었습니다.\n");	
	}
}
bool Graph::RunFloyd(int StartID)
{
	return true;
}
void Graph::CurrentView()
{
	for(int i=0; i<MaxNodeCnt; i++)
	{
		NodeData *CurrentNode = VertexList[i].GetFirstPointer();

		for(CurrentNode = VertexList[i].GetFirstPointer(); CurrentNode != VertexList[i].GetLastPointer(); CurrentNode = CurrentNode->NextNode)
			printf("%d번쨰 노드에 연결된 노드 %d의 가중치 = %d\n", i, CurrentNode->Data.vertexID, CurrentNode->Data.weight);

		if(CurrentNode != NULL)
			printf("%d번쨰 노드에 연결된 노드 %d의 가중치 = %d\n", i, CurrentNode->Data.vertexID, CurrentNode->Data.weight);
	}
}

void main()
{
	Graph MyGraph;
	printf("다익스트라, 플로이드 알고리즘 적용한 길찾기 프로그램.\n");
	printf("Programmed By Sol Choe\n\n");
	if(MyGraph.CreateGraph())
	{
		int Sel = -1, NodeSel = -1, StartSel = -1, EndSel = -1;
		printf("그래프 초기화 완료.\n");
		while(1)
		{
			printf("1. 노드 추가\n2. 노드 삭제\n3. 노드 사이의 간선 추가\n4. 노드 사이의 간선 제거\n");
			printf("5. 다익스트라 알고리즘 실행\n6. 플로이드 알고리즘 실행\n7. 현재 결과 출력\n\n");
			printf("하고자 하는 명령을 선택하세요 : ");
			scanf("%d",&Sel);

			switch(Sel)
			{
			case 1:
				printf("사용하고자 하는 노드의 슬롯을 입력하시오 : ");
				scanf("%d",&NodeSel);
				MyGraph.CreateNode(NodeSel);
				break;
			case 2:
				printf("삭제하고자 하는 노드의 슬롯을 입력하시오 : ");
				scanf("%d",&NodeSel);
				MyGraph.DeleteNode(NodeSel);
				break;
			case 3:
				printf("연결하고자 하는 노드의 시작ID와 끝ID를 입력하시오 : ");
				scanf("%d %d",&StartSel, &EndSel);
				MyGraph.CreateVertex(StartSel,EndSel);
				break;
			case 4:
				printf("삭제하고자 하는 간선의 노드의 시작ID와 끝ID를 입력하시오 : ");
				scanf("%d %d",&StartSel, &EndSel);
				MyGraph.DeleteVertex(StartSel,EndSel);
				break;
			case 5:
				printf("다익스트라 알고리즘을 실행하기 위한 노드의 시작ID와 끝ID를 입력하시오 : ");
				scanf("%d %d",&StartSel, &EndSel);
				MyGraph.RunDijkstra(StartSel,EndSel);
				break;
			case 6:
				printf("플로이드 알고리즘을 실행하기 위한 노드의 시작ID를 입력하시오 : ");
				scanf("%d %d",&StartSel);
				MyGraph.RunFloyd(StartSel);
				break;
			case 7:
				MyGraph.CurrentView();
				break;
			default:
				return ;
			}
			fflush(stdout);
		}
	}
	else
		return ;
}*/

// Programmed By Sol Choe (Sort)

// 정렬 (Selection Sort)

/*#include "stdafx.h"

void main()
{
	int Data[] = {80,50,70,10,60,20,40,30};

	int LeastIndex = 0;
	
	printf("정렬 전\n");

	for(int i=0; i<8; i++)
		printf("%d ", Data[i]);

	printf("\n");

	for(int i=0; i<8; i++)
	{
		for(int j=i; j<8; j++)
		{
			if(Data[LeastIndex] > Data[j])
				LeastIndex = j;
		}

		if(LeastIndex != -1)
		{
			int temp = 0;
			temp = Data[LeastIndex];
			Data[LeastIndex] = Data[i];
			Data[i] = temp;

			LeastIndex = i+1;
		}
	}

	printf("정렬 후\n");

	for(int i=0; i<8; i++)
		printf("%d ", Data[i]);
	
	printf("\n");
}*/

// Programmed By Sol Choe (Sort)

// 정렬 (Bubble Sort)

/*#include "stdafx.h"

void main()
{
	int Data[] = {80,50,70,10,60,20,40,30};

	int RoopCnt = 8;

		for(int i=RoopCnt-1; i>=0; i--)
		{
			for(int j=0; j<i; j++)
			{
				if(Data[j] > Data[j+1])
				{
					int temp = Data[j];
					Data[j] = Data[j+1];
					Data[j+1] = temp;
				}
			}
		}
		for(int i=0; i<8; i++)
			printf("%d ", Data[i]);

		printf("\n");
}
*/
// Programmed By Sol Choe (Sort)

// 정렬 (Quick Sort) -- 다시 고치시오.

/*#include "stdafx.h"
#include "Stack.h"

const int BufSize = 8;

int Q_Sort(int *Data, int Start, int End)
{
	int DirStats = 0;
	int PrevPivot = End,Pivot = End, Left = Start, Right = End;
	while(Left < Right)
	{
		if(Data[Pivot] < Data[Left])
		{
			if(Data[Right] < Data[Pivot])
			{
				int temp = Data[Right];
				Data[Right] = Data[Left];
				Data[Left] = temp;

				Left++;
			}
			else
				Right--;
		}
		else
		{
			if(Data[Right] > Data[Pivot])
			{
				int temp = Data[Right];
				Data[Right] = Data[Left];
				Data[Left] = temp;

				Right--;
			}
			else
				Left++;
		}
		if(Left == Right)
		{
			int temp = Data[Left];
			Data[Left] = Data[Pivot];
			Data[Pivot] = temp;

			return Right;
		}
	}
}

void main()
{
	int CurrentPivot = -1;
	int Data[BufSize] = {80,50,70,10,60,20,40,30};

	CurrentPivot = Q_Sort(Data,0,BufSize - 1);
	CurrentPivot = Q_Sort(Data,0,CurrentPivot - 1);
	CurrentPivot = Q_Sort(Data,CurrentPivot + 1, BufSize - 1);
	CurrentPivot = Q_Sort(Data,CurrentPivot - 3, CurrentPivot - 1);
	CurrentPivot = Q_Sort(Data,CurrentPivot + 1, CurrentPivot + 2);

	for(int i=0; i<BufSize; i++)
		printf("%d ",Data[i]);

	printf("\n");
}*/

// Programmed By Sol Choe (Sort)

// 정렬 (Insertion Sort)

/*#include "stdafx.h"

const int BufSize = 8;

void Insertion_Sort(int *Data)
{
	int temp = 0;
	int i,j;

	for(int i=1; i<BufSize; i++)
	{
		temp = Data[i];
		j = i;

		while((j>0) && Data[j-1] > temp)
		{
			Data[j] = Data[j-1];
 			j -= 1;
		}
		Data[j] = temp;
	}
}

void main()
{
	int Data[BufSize] = {80,50,70,10,60,20,40,30};
	printf("Before InsertionSort = ");
	for(int i=0; i<BufSize; i++)
		printf("%d ",Data[i]);

	printf("\n");

	Insertion_Sort(Data);

	printf("After InsertionSort = ");
	for(int i=0; i<BufSize; i++)
		printf("%d ",Data[i]);

	printf("\n");
}*/

// Programmed By Sol Choe (Sort)

// 정렬 (Shell Sort)

/*#include "stdafx.h"

const int BufSize = 8;

int interval = BufSize / 2;

void Shell_Sort(int *Data)
{	
	int RoopCnt = BufSize / 2;
	while(interval >= 1)
	{
		if(interval > 1)
		{
			for(int i=0; i<interval; i++)
			{
				for(int j=0; j<RoopCnt; j++)
				{
					if(Data[j] > Data[j+interval])
					{
						int temp = Data[j+interval];
						Data[j+interval] = Data[j];
						Data[j] = temp;
					}
				}
			}
		}
		else
		{
			int temp = 0;
			int i,j;

			for(int i=1; i<BufSize; i++)
			{
				temp = Data[i];
				j = i;

				while((j>0) && Data[j-1] > temp)
				{
					Data[j] = Data[j-1];
					j -= 1;
				}
				Data[j] = temp;
			}
		}
		interval /= 2;
		if(interval >= 1)
			RoopCnt += interval;
	}
}

void main()
{
	int Data[BufSize] = {80,50,70,10,60,20,40,30};

	printf("Before ShellSort = ");
	for(int i=0; i<BufSize; i++)
		printf("%d ",Data[i]);

	printf("\n");

	Shell_Sort(Data);

	printf("After ShellSort = ");
	for(int i=0; i<BufSize; i++)
		printf("%d ",Data[i]);

	printf("\n");
}*/

// Referenced By Book (Sort)

// 정렬 (Merge Sort)

/*#include "stdafx.h"

const int BufSize = 8;

void MergeSortInternal(int *Data, int *Buffer, int start, int middle, int end)
{
	int i=0, j=0, k=0, t=0;
	i = start;
	j = middle + 1;
	k = start;

	while(i <= middle && j <= end)
	{
		if(Data[i] <= Data[j])
		{
			Buffer[k] = Data[i];
			i++;
		}
		else
		{
			Buffer[k] = Data[j];
			j++;
		}
		k++;
	}

	if(i > middle)
	{
		for(t = j; t <= end; t++, k++)
		{
			Buffer[k] = Data[t];
		}
	}
	else
	{
		for(t = i; t <= middle; t++, k++)
		{
			Buffer[k] = Data[t];
		}
	}

	for(t = start; t <= end; t++)
	{
		Data[t] = Buffer[t];
	}

	printf("Start-%d, Middle-%d, End-%d,", start, middle, end);
	for(t = start; t <= end; t++)
	{
		printf("%d ", Data[t]);
	}
	printf("\n");
}

void Merge_Sort(int *Data, int *Buffer, int start, int end)
{
	int middle = 0;
	if(start < end)
	{
		middle = (start + end) / 2;

		Merge_Sort(Data,Buffer,start,middle);
		Merge_Sort(Data,Buffer,middle+1,end);

		MergeSortInternal(Data,Buffer,start,middle,end);
	}
}

void main()
{
	int Data[BufSize] = {80,50,70,10,60,20,40,30};
	int *Buffer = new int[BufSize];

	Merge_Sort(Data,Buffer,0,BufSize-1);

	SAFE_DELETE(Buffer);
}*/

// Programmed By Sol Choe (Sort)

// 정렬 (Bucket Sort)

/*#include "stdafx.h"
#include "Queue.h"

const int BufSize = 8;

void Bucket_Sort(Queue *Bucket,int *Data)
{
	for(int i=0; i<BufSize; i++)
	{
		NodeData *NewData = new NodeData;
		NewData->Data = Data[i];
		Bucket[Data[i] % 10].push_back(NewData);
	}

	int DataIndex = 0;

	for(int i=0; i<10; i++)
	{
		int TotalCnt = Bucket[i].GetTotalCnt();
		for(int j=0; j<TotalCnt; j++)
		{
			NodeData *DelData = NULL;
			Data[DataIndex++] = Bucket[i].GetFirstPointer()->Data;
			DelData = Bucket[i].GetFirstPointer();
			Bucket[i].pop_front();
			SAFE_DELETE(DelData);
		}
	}

	for(int i=0; i<BufSize; i++)
	{
		NodeData *NewData = new NodeData;
		NewData->Data = Data[i];
		Bucket[Data[i] / 10].push_back(NewData);
	}
	
	DataIndex = 0;

	for(int i=0; i<10; i++)
	{
		int TotalCnt = Bucket[i].GetTotalCnt();
		for(int j=0; j<TotalCnt; j++)
		{
			NodeData *DelData = NULL;
			Data[DataIndex++] = Bucket[i].GetFirstPointer()->Data;
			DelData = Bucket[i].GetFirstPointer();
			Bucket[i].pop_front();
			SAFE_DELETE(DelData);
		}
	}
}

void main()
{
	Queue Bucket[10];
	int Data[BufSize] = {42,60,75,81,10,23,12,18};

	Bucket_Sort(Bucket,Data);

	for(int i=0; i<BufSize; i++)
	{
		printf("%d ",Data[i]);
	}
}*/

// Programmed By Sol Choe (Sort)

// 정렬 (MinHeap Sort - Pointer Ver)

#include "stdafx.h"
#include "Queue.h"
#include "Stack.h"

class BinaryTree
{
public:
	BinaryTree();
	~BinaryTree();
	// 사용할 함수 구현.
public:
	NodeData *GetRoot() {return RootNode;}
	NodeData *GetCurrent() {return CurrentPoint;}
	Stack &GetDeleteStack() {return DeleteStack;}
public:
	bool InitTree(int Key);
	NodeData *getLeftChildNode(NodeData *CurrentNode);
	NodeData *getRightChildNode(NodeData *CurrentNode);
	void InsertNode(NodeData *PointNode);
	int DeleteNode();
public:
	void ViewTreeNode();
	void CheckMinHeap(NodeData *CurrentNode);
	// 내부 함수 구현.
private:
	void InsertLeftChildNode(NodeData *CurrentNode);
	void InsertRightChildNode(NodeData *CurrentNode);
private:
	NodeData *RootNode;
	NodeData *CurrentPoint;
	Queue InsertQueue;
	Stack DeleteStack;
};

BinaryTree MyTree;

BinaryTree::BinaryTree() : RootNode(NULL)
{

}
BinaryTree::~BinaryTree()
{

}

bool BinaryTree::InitTree(int Key)
{
	if(Key > 0 && RootNode == NULL)
	{
		RootNode = new NodeData;
		RootNode->Data = Key;
		printf("트리를 초기화하였습니다.\n");

		CurrentPoint = RootNode;
		InsertQueue.push_back(RootNode);

		return true;
	}
	else
	{
		printf("트리의 초기화에 실패하였거나 트리가 초기화 되어있습니다.\n");
		return false;
	}
}
NodeData *BinaryTree::getLeftChildNode(NodeData *CurrentNode)
{
	if(CurrentNode != NULL)
	{
		if(CurrentNode->LeftNode != NULL)
			return CurrentNode->LeftNode;
		else
		{
			printf("연결된 노드가 존재하지 않습니다.\n");
			return NULL;
		}
	}
	else
	{
		printf("현재 노드가 비어있는 값입니다.\n");
		return NULL;
	}
}
NodeData *BinaryTree::getRightChildNode(NodeData *CurrentNode)
{
	if(CurrentNode != NULL)
	{
		if(CurrentNode->RightNode != NULL)
			return CurrentNode->RightNode;
		else
		{
			printf("연결된 노드가 존재하지 않습니다.\n");
			return NULL;
		}
	}
	else
	{
		printf("현재 노드가 비어있는 값입니다.\n");
		return NULL;
	}
}
void BinaryTree::InsertNode(NodeData *PointNode)
{
	if(PointNode != NULL)
	{
		NodeData *TempNode = NULL;
		if(PointNode->LeftNode == NULL)
		{
			InsertLeftChildNode(PointNode);
			TempNode = PointNode->LeftNode;
		}
		else if(PointNode->RightNode == NULL)
		{
			InsertRightChildNode(PointNode);
			TempNode = PointNode->RightNode;
		}
		else
		{
			InsertQueue.push_back(PointNode->LeftNode);
			InsertQueue.push_back(PointNode->RightNode);
			InsertQueue.pop_front();

			CurrentPoint = InsertQueue.GetFirstPointer()->OriginAddr;

			printf("현재 노드의 좌우에 자료가 있습니다. 다음으로 넘어갑니다.\n");

			return ;
		}
		TempNode->OriginAddr = TempNode;

		CheckMinHeap(TempNode);
	}
	else
	{
		printf("현재 노드가 비어있는 값입니다.\n");
		return ;
	}
}
int BinaryTree::DeleteNode()
{
	NodeData *CurrentNode = MyTree.GetRoot(), *LastStackPt = DeleteStack.GetLastPointer()->OriginAddr;

	int temp = CurrentNode->Data;
	CurrentNode->Data = LastStackPt->Data;
	LastStackPt->Data = temp;

	if(LastStackPt->Parent != NULL)
	{
		if(LastStackPt->Parent->LeftNode == LastStackPt)
			LastStackPt->Parent->LeftNode = NULL;
		else if(LastStackPt->Parent->RightNode == LastStackPt)
			LastStackPt->Parent->RightNode = NULL;
	}
	else
	{
		if(LastStackPt->LeftNode == LastStackPt)
			LastStackPt->LeftNode = NULL;
		else if(LastStackPt->RightNode == LastStackPt)
			LastStackPt->RightNode = NULL;
	}

	LastStackPt->Parent = NULL;
	LastStackPt->LeftNode = NULL;
	LastStackPt->RightNode = NULL;

	DeleteStack.pop_back();

	return temp;
}
void BinaryTree::InsertLeftChildNode(NodeData *CurrentNode)
{
	if(CurrentNode != NULL)
	{
		if(CurrentNode->LeftNode == NULL)
		{
			CurrentNode->LeftNode = new NodeData;
			if(CurrentNode->LeftNode != NULL)
			{
				printf("새로 추가된 노드에 삽입할 데이터를 입력하시오 : ");
				scanf("%d",&CurrentNode->LeftNode->Data);
				CurrentNode->LeftNode->Parent = CurrentNode;
			}
			else
				printf("메모리 할당 에러\n");
		}
		else
			printf("노드에 값이 있습니다.\n");
	}
	else
		printf("현재 노드가 비어있는 값입니다.\n");
}
void BinaryTree::InsertRightChildNode(NodeData *CurrentNode)
{
	if(CurrentNode != NULL)
	{
		if(CurrentNode->RightNode == NULL)
		{
			CurrentNode->RightNode = new NodeData;
			if(CurrentNode->RightNode != NULL)
			{
				printf("새로 추가된 노드에 삽입할 데이터를 입력하시오 : ");
				scanf("%d",&CurrentNode->RightNode->Data);
				CurrentNode->RightNode->Parent = CurrentNode;
			}
			else
				printf("메모리 할당 에러\n");
		}
		else
			printf("노드에 값이 있습니다.\n");
	}
	else
		printf("현재 노드가 비어있는 값입니다.\n");
}
void BinaryTree::CheckMinHeap(NodeData *CurrentNode)
{
	while(CurrentNode->Parent != NULL)
	{
		if(CurrentNode->Parent->Data >= CurrentNode->Data)
		{
			int temp = CurrentNode->Parent->Data;
			CurrentNode->Parent->Data = CurrentNode->Data;
			CurrentNode->Data = temp;
		}
		CurrentNode = CurrentNode->Parent;
	}
}
void InitStackData()
{
	Queue InitQueue;
	NodeData *CurrentNode = MyTree.GetRoot();
	CurrentNode->OriginAddr = CurrentNode;

	MyTree.GetDeleteStack().push_back(CurrentNode);
	InitQueue.push_back(CurrentNode);

	while(CurrentNode->LeftNode != NULL || CurrentNode->RightNode != NULL)
	{
		if(CurrentNode->LeftNode != NULL)
		{
			InitQueue.push_back(CurrentNode->LeftNode);
			MyTree.GetDeleteStack().push_back(CurrentNode->LeftNode);
		}

		if(CurrentNode->RightNode != NULL)
		{
			InitQueue.push_back(CurrentNode->RightNode);
			MyTree.GetDeleteStack().push_back(CurrentNode->RightNode);
		}

		InitQueue.pop_front();

		CurrentNode = InitQueue.GetFirstPointer();
	}
	InitQueue.clear();
}
void InHeapSort()
{
	InitStackData();
	NodeData *CurrentNode = MyTree.GetRoot();
	while(MyTree.GetDeleteStack().GetTotalCnt() > 0)
	{
		int Ret = MyTree.DeleteNode();
		while(CurrentNode != NULL)
		{
			int temp;
			if(CurrentNode->LeftNode != NULL && CurrentNode->RightNode != NULL)
			{
				if(CurrentNode->LeftNode->Data >= CurrentNode->RightNode->Data)
				{
					temp = CurrentNode->RightNode->Data;
					CurrentNode->RightNode->Data = CurrentNode->Data;
					CurrentNode->Data = temp;

					CurrentNode = CurrentNode->RightNode;
				}
				else
				{
					temp = CurrentNode->LeftNode->Data;
					CurrentNode->LeftNode->Data = CurrentNode->Data;
					CurrentNode->Data = temp;

					CurrentNode = CurrentNode->LeftNode;
				}
			}
			else
			{
				if(CurrentNode->LeftNode != NULL)
				{
					if(CurrentNode->LeftNode->Data <= CurrentNode->Data)
					{
						temp = CurrentNode->LeftNode->Data;
						CurrentNode->LeftNode->Data = CurrentNode->Data;
						CurrentNode->Data = temp;
					}
					CurrentNode = CurrentNode->LeftNode;
				}
				else if(CurrentNode->RightNode != NULL)
				{
					if(CurrentNode->RightNode->Data <= CurrentNode->Data)
					{
						temp = CurrentNode->RightNode->Data;
						CurrentNode->RightNode->Data = CurrentNode->Data;
						CurrentNode->Data = temp;
					}
					CurrentNode = CurrentNode->RightNode;
				}
				else
					CurrentNode = CurrentNode->LeftNode;
			}
		}
		CurrentNode = MyTree.GetRoot();

		printf("%d\n", Ret);
	}
}

void main()
{
	printf("큐를 이용한 최소 히프 정렬 프로그램 입니다.\n");
	MyTree.InitTree(20);
	while(1)
	{
		int swit;
	
		printf("1. 자료 삽입 2. 자료 정렬\n");
		printf("명령을 입력해주세요 : ");
		scanf("%d",&swit);

		switch(swit)
		{
		case 1:
			MyTree.InsertNode(MyTree.GetCurrent());
			break;
		case 2:
			InHeapSort();
			break;
		}
	}
}